package com.ruoyi.system.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.system.domain.RedisDataInfo;
import com.ruoyi.system.service.ISysRedisKeyService;
import com.ruoyi.system.service.ISysRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author wjialong
 */
@RestController
@RequestMapping("/redis/key")
public class SysRedisKeyController {
    @Autowired
    ISysRedisService redisService;

    @Autowired
    ISysRedisKeyService keyService;

    @Autowired
    ObjectMapper objectMapper;


    /**
     * 获取数据库的key列表
     *
     * @param redisDataInfo 包括redisId、dbId
     * @param pattern       查找key匹配的表达式
     * @return
     */
    @GetMapping("/list")
    public TableDataInfo getKeyList(RedisDataInfo redisDataInfo, String pattern, String sort,
                                    Integer pageNum, Integer pageSize) {
        // 默认匹配格式为全匹配
        if (pattern == null) {
            pattern = "*";
        }
        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        TableDataInfo resultTable;
        if (redisDataInfo.getRedisId() == null) {
            resultTable = new TableDataInfo();
            resultTable.setCode(500);
            resultTable.setMsg("redis服务器连接失败");
            return resultTable;
        }
        try {
            resultTable = keyService.getKeyList(redisDataInfo, pattern, sort, pageNum, pageSize);
        } catch (Exception e) {
            resultTable = new TableDataInfo();
            resultTable.setCode(500);
            resultTable.setMsg("redis服务器连接失败");
        }
        return resultTable;
    }

    /**
     * 获取单个key的信息
     *
     * @param redisDataInfo
     * @return
     */
    @GetMapping
    public AjaxResult getKeyInfo(RedisDataInfo redisDataInfo) {
        try {
            keyService.getKeyInfo(redisDataInfo);
        } catch (RedisConnectionFailureException e) {
            return AjaxResult.error("redis服务器连接失败");
        }
        return AjaxResult.success(redisDataInfo);
    }

    /**
     * 新增key
     *
     * @param redisDataInfo
     * @return
     */
    @PostMapping
    public AjaxResult addKey(@RequestBody RedisDataInfo redisDataInfo) {
        try {
            if (!keyService.addKey(redisDataInfo)) {
                return AjaxResult.error("新增失败，该key已存在");
            }
        } catch (RedisConnectionFailureException e) {
            return AjaxResult.error("redis服务器连接失败");
        }
        return AjaxResult.success();
    }

    /**
     * 删除key
     *
     * @param redisDataInfo
     * @return
     */
    @DeleteMapping
    public AjaxResult deleteKey(@RequestBody RedisDataInfo redisDataInfo) {
        try {
            keyService.deleteKey(redisDataInfo);
        } catch (RedisConnectionFailureException e) {
            return AjaxResult.error("redis服务器连接失败");
        }
        return AjaxResult.success();
    }

    /**
     * 删除所有key
     *
     * @param redisDataInfo
     * @return
     */
    @DeleteMapping("/all")
    public AjaxResult deleteAllKey(@RequestBody RedisDataInfo redisDataInfo) {
        try {
            keyService.deleteAllKey(redisDataInfo);
        } catch (RedisConnectionFailureException e) {
            return AjaxResult.error("redis服务器连接失败");
        }
        return AjaxResult.success();
    }

    @DeleteMapping("/pattern")
    public AjaxResult deleteKeys(RedisDataInfo redisDataInfo, String pattern) {
        try {
            keyService.deleteKeys(redisDataInfo, pattern);
        } catch (RedisConnectionFailureException e) {
            return AjaxResult.error("redis服务器连接失败");
        }
        return AjaxResult.success();
    }

    /**
     * key重命名
     *
     * @return
     */
    @PostMapping("/rename")
    public AjaxResult renameKey(@RequestBody Map<String, Object> map) {
        // 手动读取参数 -- 也可以去设计一个vo实体类来接收参数
        RedisDataInfo redisDataInfo = new RedisDataInfo();
        redisDataInfo.setRedisId((String) map.get("redisId"));
        redisDataInfo.setDbId(Integer.parseInt((String) map.get("dbId")));
        String oldKey = (String) map.get("oldKey");
        String newKey = (String) map.get("newKey");

        try {
            if (!keyService.renameKey(redisDataInfo, oldKey, newKey)) {
                return AjaxResult.error("重命名失败，newKey已存在");
            }
        } catch (RedisConnectionFailureException e) {
            return AjaxResult.error("redis服务器连接失败");
        } catch (Exception e) {
            return AjaxResult.error("数据不存在");
        }
        return AjaxResult.success();

    }

    /**
     * 设置key的超时时间
     *
     * @param redisDataInfo
     * @return
     */
    @PostMapping("/ttl")
    public AjaxResult setTTL(@RequestBody RedisDataInfo redisDataInfo) {
        StringRedisTemplate redisTemplate = redisService.getRedisTemplate(redisDataInfo);
        if (!redisService.testConnect(redisTemplate)) {
            return AjaxResult.error("redis服务器连接失败");
        }
        String key = redisDataInfo.getKey();
        Long ttl = redisDataInfo.getTtl();
        if (ttl <= 0) {
            redisTemplate.persist(key);
            return AjaxResult.success();
        }
        try {
            if (Boolean.TRUE.equals(redisTemplate.expire(
                    key, ttl, TimeUnit.SECONDS))) {
                return AjaxResult.success();
            } else {
                return AjaxResult.error("设置失败");
            }
        } finally {
            redisTemplate.getConnectionFactory().getConnection().close();
        }

    }


}